package middleware

import (
	"fmt"
	"x-admin/backend/pkg/response"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// PermissionMiddleware 权限中间件
func PermissionMiddleware(db *gorm.DB, requiredPermission string) gin.HandlerFunc {
	return func(c *gin.Context) {
		// 如果没有指定权限要求，直接通过
		if requiredPermission == "" {
			c.Next()
			return
		}

		// 获取用户ID
		userID, exists := c.Get("user_id")
		if !exists {
			response.Forbidden(c, "用户未认证")
			c.Abort()
			return
		}

		// 检查用户权限
		hasPermission, err := checkUserPermission(db, userID.(uint), requiredPermission)
		if err != nil {
			response.InternalServerError(c, "权限检查失败: "+err.Error())
			c.Abort()
			return
		}

		if !hasPermission {
			response.Forbidden(c, fmt.Sprintf("缺少权限: %s", requiredPermission))
			c.Abort()
			return
		}

		c.Next()
	}
}

// Role 角色模型（用于权限检查）
type Role struct {
	ID        uint           `json:"id" gorm:"primaryKey"`
	Code      string         `json:"code"`
	Status    int            `json:"status"`
	DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"`
}

// Permission 权限模型（用于权限检查）
type Permission struct {
	ID        uint           `json:"id" gorm:"primaryKey"`
	Code      string         `json:"code"`
	Status    int            `json:"status"`
	DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"`
}

// UserRole 用户角色关联模型
type UserRole struct {
	UserID uint `json:"user_id" gorm:"primaryKey"`
	RoleID uint `json:"role_id" gorm:"primaryKey"`
	Role   Role `json:"role" gorm:"foreignKey:RoleID;references:ID"`
}

// RolePermission 角色权限关联模型
type RolePermission struct {
	RoleID       uint       `json:"role_id" gorm:"primaryKey"`
	PermissionID uint       `json:"permission_id" gorm:"primaryKey"`
	Permission   Permission `json:"permission" gorm:"foreignKey:PermissionID;references:ID"`
}

// checkUserPermission 检查用户是否拥有指定权限
func checkUserPermission(db *gorm.DB, userID uint, permissionCode string) (bool, error) {
	// 首先检查用户是否是超级管理员
	var userRoles []UserRole
	err := db.Preload("Role").Where("user_id = ?", userID).Find(&userRoles).Error
	if err != nil {
		return false, err
	}

	// 检查是否有admin角色
	for _, ur := range userRoles {
		if ur.Role.Code == "admin" && ur.Role.Status == 1 {
			return true, nil // 超级管理员拥有所有权限
		}
	}

	// 检查用户是否通过角色拥有该权限
	var roleIDs []uint
	for _, ur := range userRoles {
		if ur.Role.Status == 1 { // 只考虑启用的角色
			roleIDs = append(roleIDs, ur.RoleID)
		}
	}

	if len(roleIDs) == 0 {
		return false, nil
	}

	// 查询角色权限
	var rolePermissions []RolePermission
	err = db.Preload("Permission").Where("role_id IN ? ", roleIDs).Find(&rolePermissions).Error
	if err != nil {
		return false, err
	}

	// 检查是否有匹配的权限
	for _, rp := range rolePermissions {
		if rp.Permission.Code == permissionCode && rp.Permission.Status == 1 {
			return true, nil
		}
	}

	return false, nil
}

// RequirePermission 创建需要特定权限的中间件
func RequirePermission(db *gorm.DB, permissionCode string) gin.HandlerFunc {
	return PermissionMiddleware(db, permissionCode)
}

// PermissionGroup 权限路由组，用于批量设置权限
type PermissionGroup struct {
	group *gin.RouterGroup
	db    *gorm.DB
}

// NewPermissionGroup 创建权限路由组
func NewPermissionGroup(group *gin.RouterGroup, db *gorm.DB) *PermissionGroup {
	return &PermissionGroup{
		group: group,
		db:    db,
	}
}

// GET 带权限检查的GET路由
func (pg *PermissionGroup) GET(relativePath string, permission string, handlers ...gin.HandlerFunc) gin.IRoutes {
	allHandlers := []gin.HandlerFunc{RequirePermission(pg.db, permission)}
	allHandlers = append(allHandlers, handlers...)
	return pg.group.GET(relativePath, allHandlers...)
}

// POST 带权限检查的POST路由
func (pg *PermissionGroup) POST(relativePath string, permission string, handlers ...gin.HandlerFunc) gin.IRoutes {
	allHandlers := []gin.HandlerFunc{RequirePermission(pg.db, permission)}
	allHandlers = append(allHandlers, handlers...)
	return pg.group.POST(relativePath, allHandlers...)
}

// PUT 带权限检查的PUT路由
func (pg *PermissionGroup) PUT(relativePath string, permission string, handlers ...gin.HandlerFunc) gin.IRoutes {
	allHandlers := []gin.HandlerFunc{RequirePermission(pg.db, permission)}
	allHandlers = append(allHandlers, handlers...)
	return pg.group.PUT(relativePath, allHandlers...)
}

// DELETE 带权限检查的DELETE路由
func (pg *PermissionGroup) DELETE(relativePath string, permission string, handlers ...gin.HandlerFunc) gin.IRoutes {
	allHandlers := []gin.HandlerFunc{RequirePermission(pg.db, permission)}
	allHandlers = append(allHandlers, handlers...)
	return pg.group.DELETE(relativePath, allHandlers...)
}

// PATCH 带权限检查的PATCH路由
func (pg *PermissionGroup) PATCH(relativePath string, permission string, handlers ...gin.HandlerFunc) gin.IRoutes {
	allHandlers := []gin.HandlerFunc{RequirePermission(pg.db, permission)}
	allHandlers = append(allHandlers, handlers...)
	return pg.group.PATCH(relativePath, allHandlers...)
}

// Group 创建子权限路由组
func (pg *PermissionGroup) Group(relativePath string) *PermissionGroup {
	return NewPermissionGroup(pg.group.Group(relativePath), pg.db)
}

// Use 添加中间件到权限路由组
func (pg *PermissionGroup) Use(middleware ...gin.HandlerFunc) gin.IRoutes {
	return pg.group.Use(middleware...)
}

// Any 带权限检查的Any路由
func (pg *PermissionGroup) Any(relativePath string, permission string, handlers ...gin.HandlerFunc) gin.IRoutes {
	allHandlers := []gin.HandlerFunc{RequirePermission(pg.db, permission)}
	allHandlers = append(allHandlers, handlers...)
	return pg.group.Any(relativePath, allHandlers...)
}

// Handle 带权限检查的Handle路由
func (pg *PermissionGroup) Handle(httpMethod, relativePath string, permission string, handlers ...gin.HandlerFunc) gin.IRoutes {
	allHandlers := []gin.HandlerFunc{RequirePermission(pg.db, permission)}
	allHandlers = append(allHandlers, handlers...)
	return pg.group.Handle(httpMethod, relativePath, allHandlers...)
}
